package org.flowers.unbeaten.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.flowers.unbeaten.base.constant.Constants;
import org.flowers.unbeaten.config.proprety.CustomerRedisProperty;
import org.flowers.unbeaten.exception.BusinessException;
import org.flowers.unbeaten.exception.code.BaseResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.Objects;

/**
 * @description 自定义Realm
 * @author RyanWang
 * @date 2021-07-16 15:32:15
 * @version 1.0
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CustomerRedisProperty customerRedisProperty;

    /**
     * 执行授权逻辑
     * @param principalCollection
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        String sessionInfoStr = (String) redisTemplate.opsForValue().get(customerRedisProperty.getUserTokenPrefix() + principalCollection.getPrimaryPrincipal());
        if (StringUtils.isEmpty(sessionInfoStr)) {
            throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
        }

        JSONObject redisSession = JSON.parseObject(sessionInfoStr);
        if (redisSession == null) {
            throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
        }

        if (Objects.nonNull(redisSession.get(Constants.ROLES_KEY))) {
            authorizationInfo.addRoles((Collection<String>) redisSession.get(Constants.ROLES_KEY));
        }

        if (Objects.nonNull(redisSession.get(Constants.PERMISSIONS_KEY))) {
            authorizationInfo.addStringPermissions((Collection<String>) redisSession.get(Constants.PERMISSIONS_KEY));
        }
        return authorizationInfo;
    }

    /**
     * 执行认证逻辑
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        return new SimpleAuthenticationInfo(authenticationToken.getPrincipal(), authenticationToken.getPrincipal(), getName());
    }

}
